-module(receiver).
-export([start/7]).
-import(synchro, [get_time/1]).

start(DataSource, SynchroPID, OutputPID, SlotselectionPID, ListenToPort, IP, MultIP) -> %evt. fehlende Startparameter auch im tdmaclient:start nachtragen
spawn(fun() -> start_server(DataSource, ListenToPort, IP, MultIP, SynchroPID, OutputPID, SlotselectionPID) end).

start_server(DataSource, ListenToPort, IP, MultIP, SynchroPID, OutputPID, SlotselectionPID) ->
    Socket = get_socket(receiver, ListenToPort, IP, MultIP),
    start_listening(DataSource, Socket, SynchroPID, OutputPID, SlotselectionPID, undefined).

start_listening(DataSource, Socket, SynchroPID, OutputPID, SlotselectionPID, LastReceivedSlot) ->
    receive
        {udp, Socket, _, _, Bin} ->%%Bin == packet, falls funktioniert
            CurrentTimestamp = get_time(SynchroPID),
            CurrentSlot = round((CurrentTimestamp rem 1000) / 40 -0.5),
            FrameNr = round((CurrentTimestamp/1000)-0.5)+1, 
            %ExpectedTime = FrameNr * 1000 + CurrentSlot * 40 + 20,
            if 
                CurrentSlot == LastReceivedSlot ->
                    SlotselectionPID ! {collision, CurrentSlot};
                true -> ok
            end,
            %%magic:D
            <<Nutzdaten:24/bytes,Station:1/bytes, ReservedSlot:8/integer,ExpectedTime:64/integer-big>> = Bin,
            DataSource ! {getstation, self()},
            receive
                {station, StationIdent} -> ok
            end,
            DataStationIdent = lists:sublist(binary_to_list(Nutzdaten),10),
            case binary_to_list(Station) of
            	"A" when DataStationIdent /= StationIdent -> 
                    SynchroPID ! {sync, CurrentTimestamp, ExpectedTime}; %Eingangszeitstempel nutzen!
                _ -> 
                    ok
            end,
            
            SlotselectionPID ! {CurrentSlot, FrameNr, ReservedSlot},
            %io:format("Nutzdaten erhalten~p~n", [binary_to_list(Nutzdaten)]),
            %OutputPID ! lists:concat(["Nachricht erhalten: ", binary_to_list(Nutzdaten)]),
            start_listening(DataSource, Socket, SynchroPID, OutputPID, SlotselectionPID, CurrentSlot)
    end.

%%Ganz wichtig! Diese Funktion nur einmal aufrufen und Rückgabewert in einer Variablen speichern!
get_socket(receiver,Port,IP,MultIP)-> %IP ist hier immer die eigene IP (Networkinterface)
    {ok,Socket}=gen_udp:open(Port,[binary, {active, true},
                                        {reuseaddr,true},
                                        {multicast_if, IP},
                                        inet,{multicast_ttl, 255},
                                        {multicast_loop, false},
                                        {add_membership, {MultIP,IP}}]),
    Socket.

%%Usage
%%Socket=tools:get_socket(receiver,Port,Ip, MultIp),
%%gen_udp:controlling_process(Socket,self()),

%%{ok, {Addr, Port, Packet}} = gen_udp:recv(Socket, Length [, Timeout])
%%<<Team:10/bytes,_:14,Type/bits:1,Slot/integer:1,TimeStamp/integer:8-big>> = Packet.gen_udp:controlling_process(Socket,self()),